package cn.jiaqiang.chatgpt.data.infrastructure.repository;

import cn.jiaqiang.chatgpt.data.domain.weixin.repository.IWeiXinRepository;
import cn.jiaqiang.chatgpt.data.infrastructure.redis.IRedisService;
import cn.jiaqiang.chatgpt.data.types.common.RedisConstants;
import cn.jiaqiang.chatgpt.data.types.sdk.code.RandomCodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

import static cn.jiaqiang.chatgpt.data.types.common.RedisConstants.OPENAI_CODE_EXPIRED;

/**
 * @description 微信服务仓储
 */
@Slf4j
@Repository
public class WeiXinRepository implements IWeiXinRepository {

    private static final String Key = RedisConstants.OPENAI_CODE_PREFIX;
    private static final String Separator = RedisConstants.SEPARATOR;

    @Resource
    private IRedisService redisService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public String generateCode(String userId, String openId) {
        log.info("开始生成验证码...");
        // 获取值
        String isExitCode = stringRedisTemplate.opsForValue().get(Key + Separator + userId);
        if (StringUtils.isNotBlank(isExitCode)) {
            return isExitCode;
        }

        /* 生成值, 使用 uuid 也不是不行, 只是 uuid 太多了, 用户不好输入.
          String code = UUID.randomUUID().toString().replace("-", "");
          stringRedisTemplate.opsForValue().set(code,userBehaviorMessageEntity.getOpenId(), 1L, TimeUnit.MINUTES);
         */
        RLock lock = redisService.getLock(Key + Separator);
        try {
            lock.lock(15, TimeUnit.SECONDS);
            /* RandomStringUtils.randomNumeric(4) */
            String code = RandomCodeUtil.generateComplexCode(4);
            // 防重校验&重新生成
            for (int i = 0; i < 10 && StringUtils.isNotBlank(stringRedisTemplate.opsForValue().get(Key + Separator + userId)); i++) {
                if (i < 3) {
                    code = RandomCodeUtil.generateComplexCode(4);
                } else if (i < 5) {
                    log.info("验证码重复，生成6位字符串验证码 {} {}", userId, code);
                    code = RandomCodeUtil.generateComplexCode(5);
                } else if (i < 9) {
                    code = RandomCodeUtil.generateComplexCode(6);
                    log.warn("验证码重复，生成6位字符串验证码 {} {}", userId, code);
                } else {
                    return "您的验证码获取失败，请重新回复获取。";
                }
            }

            // 存储值【3分钟有效期】
            stringRedisTemplate.opsForValue().set(Key + Separator + code, openId, OPENAI_CODE_EXPIRED, TimeUnit.MINUTES);
            stringRedisTemplate.opsForValue().set(Key + Separator + openId, userId, OPENAI_CODE_EXPIRED, TimeUnit.MINUTES);
            stringRedisTemplate.opsForValue().set(Key + Separator + userId, code, OPENAI_CODE_EXPIRED, TimeUnit.MINUTES);
            log.info("验证码生成完成: {}", code);
            return code;
        } finally {
            lock.unlock();
        }
    }

}
